package cn.yueranzs.login.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import cn.yueranzs.handler.BusinessException;
import cn.yueranzs.response.RedisResultCode;
import cn.yueranzs.response.UserResultCode;
import cn.yueranzs.system.pojo.User;
import cn.yueranzs.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

/**
 * 描述：自定义SpringSecurity的认证器
 * @author yueranzs
 * @date 2021/12/1 9:44
 */
@Component
public class LoginAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private LoginUserDetails loginUserDetails;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        return null;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //用户名
        String username = authentication.getName();
        //密码
        String password = authentication.getCredentials().toString();
        LoginWebAuthenticationDetails loginWebAuthenticationDetails= (LoginWebAuthenticationDetails)authentication.getDetails();
        //验证码key
        String randomCode = loginWebAuthenticationDetails.getRandomCode();
        //验证码value
        String code = loginWebAuthenticationDetails.getCode();
        //验证码是否为空
        if (ObjectUtil.isEmpty(randomCode) || ObjectUtil.isEmpty(code)) {
            throw new NullPointerException("请输入验证码");
        }
        //检验验证码是否正确
        if (!validateVerifyRandomCode(randomCode,code)) {
            throw new BusinessException(UserResultCode.REDIS_CODE.getCode(), UserResultCode.REDIS_CODE.getMessage());
        }
        User user = (User) loginUserDetails.loadUserByUsername(username);
        //密码是否一致
        if (!user.getPassword().equals(SecureUtil.md5(password))) {
            throw new BadCredentialsException(UserResultCode.USER_CREDENTIALS_ERROR.getMessage());
        }
        //删除redis的验证码
        RedisUtil.del(RedisResultCode.REDIS_RANDOM_CODE.getMessage() + randomCode);

        return this.createSuccessAuthentication(user,authentication,user);
    }

    /**
     * 验证用户输入的验证码
     * @param randomCode 验证码key
     * @param code 验证码value
     * @return
     */
    public boolean validateVerifyRandomCode(String randomCode,String code){
        //验证码是否一致
        Object redisCode = RedisUtil.get(RedisResultCode.REDIS_RANDOM_CODE.getMessage() + randomCode);
        return ObjectUtil.equals(code, redisCode);
    }
}
